﻿using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace Sharp.Platform.Mvc.Bootstrap
{
    /// <summary>
    /// DropdownList建设者。
    /// </summary>
    public class DropdownListBuilder : TagElementBuilder<DropdownListBuilder>
    {
        #region Field

        private readonly TypeConfiguration _typeConfiguration;
        private readonly DropdownListSizeConfiguration _DropdownListSizeConfiguration;
        private readonly DropdownListStyleConfiguration _DropdownListStyleConfiguration;


        #endregion Field

        #region Constructor

        public DropdownListBuilder()
        {
            _typeConfiguration = new TypeConfiguration(this);
            _DropdownListSizeConfiguration = new DropdownListSizeConfiguration(this);
            _DropdownListStyleConfiguration = new DropdownListStyleConfiguration(this);
            AddClass("btn-group").Style();
            Simple = false;
        }

        #endregion Constructor

        #region Public Method

        /// <summary>
        /// 标题
        /// </summary>
        public string Title
        {
            get { return TagBuilder.InnerHtml; }
            set { TagBuilder.SetInnerText(value); }
        }

        //public DropdownListBuilder Name(string name)
        //{
        //    TagBuilder.SetInnerText(name);
        //    return this;
        //}

        public TypeConfiguration Type()
        {
            return _typeConfiguration;
        }

        public DropdownListSizeConfiguration Size()
        {
            return _DropdownListSizeConfiguration;
        }

        public DropdownListBuilder Active(bool? active = null)
        {
            if (active.HasValue)
                return active.Value ? AddClass("active") : RemoveClass("active");

            return ToggleClass("active");
        }

        public DropdownListBuilder Disabled(bool disabled = true)
        {
            if (disabled)
                return Attribute("disabled", "disabled", true);
            TagBuilder.Attributes.Remove("disabled");
            return this;
        }

        public DropdownListStyleConfiguration Style()
        {
            return _DropdownListStyleConfiguration;
        }


        public DropdownListBuilder Click(string click)
        {
            return Attribute("onclick", click, true);
        }

        #endregion Public Method

        #region Overrides of TagElementBuilder<DropdownListBuilder>

        public override string TagName
        {
            get { return "DropdownList"; }
        }
        /// <summary>
        /// 数据源
        /// </summary>
        public IEnumerable DataSource { get; set; }

        public string DisplayField { get; set; }
        public string ValueField { get; set; }

        public string SelectedValue { get; set; }
        /// <summary>
        /// 简单样式（录入界面用的）
        /// </summary>
        public bool Simple { get; set; }
        /// <summary>
        /// 返回 HTML 编码的字符串。
        /// </summary>
        /// <returns>
        /// HTML 编码的字符串。
        /// </returns>
        public override string ToHtmlString()
        {
            /*
              <div class="btn-group m-r m-b">
                  <button data-toggle="dropdown" class="btn btn-sm btn-default dropdown-toggle btn-custom">
                    <span class="dropdown-label pull-left wrapper-sm">超级管理员</span> 

                    <span class="btn-caret pull-right"><span class="caret"></span></span>
                  </button>
                  <ul class="dropdown-menu dropdown-select btn-ul scrollable">
                      <li class="active"><a href="#"><input type="radio" name="d-s-r" checked="">超级管理员</a></li>
                      <li><a href="#"><input type="radio" name="d-s-r">校管理员</a></li>
                      <li><a href="#"><input type="radio" name="d-s-r">院管理员</a></li>
                      <li><a href="#"><input type="radio" name="d-s-r">系管理员</a></li>
                  </ul>
                </div>    
             */

            //为了搜索栏那里的大小，先注释掉这里
            //TagBuilder.AddCssClass(_DropdownListStyleConfiguration.ToString());

            var builder = new StringBuilder();

            builder.AppendLine(TagBuilder.ToString(TagRenderMode.StartTag).Replace(TagName, "div"));

            if (Simple)
            {
                builder.AppendLine(@"<button data-toggle=""dropdown"" class=""btn btn-default dropdown-toggle"">
                    <span class=""dropdown-label"">{SelectedText}</span> 
                    <span class=""caret""></span>
                  </button>");
            }
            else
            {
                builder.AppendLine(@"<button data-toggle=""dropdown"" class=""btn btn-sm btn-default dropdown-toggle btn-custom"">
                    <span class=""dropdown-label pull-left wrapper-sm"">{SelectedText}</span> 
                    <span class=""btn-caret pull-right""><span class=""caret""></span></span>
                  </button>");

            }
            builder.AppendLine("<ul class=\"dropdown-menu dropdown-select btn-ul scrollable\" style=\"max-height:375px;\">");

            builder.AppendFormat("<li><a href=\"#\"><input type=\"radio\" value=\"\" name=\"{0}\" />{1}</a></li>", this.TagBuilder.Attributes["name"], this.Title);

            if (this.DataSource != null)
            {
                Type type = null;
                foreach (var item in this.DataSource)
                {
                    if (type == null)
                        type = item.GetType();
                    if (type == typeof(Enum))
                    {
                        DataSourceItemEnum(item, builder);
                    }
                    else if (!type.IsValueType && type != typeof(string))
                    {
                        DataSourceItemReferenceType(item, builder);
                    }
                    else
                    {
                        DataSourceItemCommon(item, builder);
                    }
                }
            }

            builder.AppendLine("</ul>");
            builder.AppendLine(TagBuilder.ToString(TagRenderMode.EndTag).Replace(TagName, "div"));


            builder.Replace("{SelectedText}", this.Title);

            return new HtmlString(builder.ToString()).ToHtmlString();
        }

        private void DataSourceItemReferenceType(object item, StringBuilder builder)
        {
            if (this.DisplayField.IsNullOrEmpty())
            {
                throw new NotImplementedException("DisplayField属性未赋值");
            }
            else
            {
                if (this.ValueField.IsNullOrEmpty())
                {
                    this.ValueField = this.DisplayField;
                }
            }
            #region 实体类

            var valueFieldProperty = item.GetType().GetProperty(ValueField);
            var displayFieldProperty = item.GetType().GetProperty(DisplayField);

            object text = displayFieldProperty.GetValue(item, null);
            object value = valueFieldProperty.GetValue(item, null);

            if (!this.SelectedValue.IsNullOrEmpty() &&
                this.SelectedValue.Equals(value.ToString(), StringComparison.CurrentCultureIgnoreCase))
            {
                builder.Replace("{SelectedText}", displayFieldProperty.GetValue(item, null).ToString());
                builder.Append("\r\n<li class=\"active\">");

                var name = this.TagBuilder.Attributes.Keys.Contains("name")
                    ? this.TagBuilder.Attributes["name"]
                    : this.TagBuilder.Attributes["id"];

                builder.AppendFormat(
                    "<a href=\"javascript:void(0)\"><input type=\"radio\" checked=\"checked\" name=\"{2}\" value=\"{0}\">{1}</a></li>\r\n",
                    value, text, name);
            }
            else
            {
                builder.Append("\r\n<li>");
                builder.AppendFormat(
                    "<a href=\"javascript:void(0)\"><input type=\"radio\" name=\"{2}\" value=\"{0}\">{1}</a></li>\r\n",
                    value, text, this.TagBuilder.Attributes["name"]);
            }

            #endregion
        }

        private void DataSourceItemCommon(object item, StringBuilder builder)
        {
            if (!this.SelectedValue.IsNullOrEmpty() && this.SelectedValue.Equals(item.ToString(),
                           StringComparison.CurrentCultureIgnoreCase))
            {
                builder.Replace("{SelectedText}", item.ToString());
                builder.Append("\r\n<li class=\"active\">");

                builder.AppendFormat(
                    "<a href=\"javascript:void(0)\"><input type=\"radio\" checked=\"checked\" name=\"{2}\" value=\"{0}\">{1}</a></li>\r\n",
                    item, item, this.TagBuilder.Attributes["id"]);
            }
            else
            {
                builder.Append("\r\n<li>");
                builder.AppendFormat(
                    "<a href=\"javascript:void(0)\"><input type=\"radio\" name=\"{2}\" value=\"{0}\">{1}</a></li>\r\n",
                    item, item, this.TagBuilder.Attributes["id"]);
            }
        }

        private void DataSourceItemEnum(object objitem, StringBuilder builder)
        {
            #region 枚举
            Enum item = (Enum)objitem;
            if (!this.SelectedValue.IsNullOrEmpty() &&
                this.SelectedValue.Equals(Convert.ToInt32(item).ToString(),
                    StringComparison.CurrentCultureIgnoreCase))
            {
                builder.Replace("{SelectedText}", item.ToString());
                builder.Append("\r\n<li class=\"active\">");

                builder.AppendFormat(
                    "<a href=\"javascript:void(0)\"><input type=\"radio\" checked=\"checked\" name=\"{2}\" value=\"{0}\">{1}</a></li>\r\n",
                    Convert.ToInt32(item), item.GetDescription(), this.TagBuilder.Attributes["id"]);
            }
            else
            {
                builder.Append("\r\n<li>");
                builder.AppendFormat(
                    "<a href=\"javascript:void(0)\"><input type=\"radio\" name=\"{2}\" value=\"{0}\">{1}</a></li>\r\n",
                    Convert.ToInt32(item), item.GetDescription(), this.TagBuilder.Attributes["id"]);
            }

            #endregion
        }

        #endregion Overrides of TagElementBuilder<DropdownListBuilder>

        #region Overrides of Object

        /// <summary>
        /// 返回表示当前 <see cref="T:System.Object"/> 的 <see cref="T:System.String"/>。
        /// </summary>
        /// <returns>
        /// <see cref="T:System.String"/>，表示当前的 <see cref="T:System.Object"/>。
        /// </returns>
        public override string ToString()
        {
            return ToHtmlString();
        }

        #endregion Overrides of Object

        #region Help Class

        public sealed class TypeConfiguration
        {
            private readonly DropdownListBuilder _dropdownListBuilder;

            public TypeConfiguration(DropdownListBuilder dropdownListBuilder)
            {
                _dropdownListBuilder = dropdownListBuilder;
                //DropdownList();
            }

            //public DropdownListBuilder DropdownList()
            //{
            //    return _dropdownListBuilder.Attribute("type", "DropdownList", true);
            //}

        }

        public sealed class DropdownListSizeConfiguration : SizeConfiguration<DropdownListBuilder>
        {
            public DropdownListSizeConfiguration(DropdownListBuilder tagElementBuilder)
                : base("btn", tagElementBuilder)
            {
            }

            public DropdownListBuilder ExtraSmall()
            {
                Value = "btn-xs";
                return TagElementBuilder;
            }
        }

        public sealed class DropdownListStyleConfiguration : StyleConfiguration<DropdownListBuilder>
        {
            public DropdownListStyleConfiguration(DropdownListBuilder instance)
                : base("btn", instance)
            {
            }

            public DropdownListBuilder Link()
            {
                Value = "btn-link";

                return Instance;
            }
        }

        #endregion Help Class
    }
}